package cn.coisini.service.impl;

import cn.coisini.mapper.ArticleTagMapper;
import cn.coisini.mapper.TagMapper;
import cn.coisini.model.common.dtos.Result;
import cn.coisini.model.common.enums.ResultEnum;
import cn.coisini.model.pojo.ArticleTag;
import cn.coisini.model.pojo.Tag;
import cn.coisini.model.pojo.User;
import cn.coisini.model.vo.QueryVo;
import cn.coisini.model.vo.TagVo;
import cn.coisini.service.TagService;
import cn.coisini.service.UserService;
import cn.coisini.utils.IdWorker;
import cn.hutool.core.text.CharSequenceUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.*;

import static cn.coisini.model.common.constants.AdminConstants.CREATE_USER;
import static cn.coisini.utils.JwtUtil.getUserIdFromToken;

/**
 * @author xiangshaw
 * Description: 标签实现类
 */
@Service
@RequiredArgsConstructor
public class TagServiceImpl extends ServiceImpl<TagMapper, Tag> implements TagService {

    private final ArticleTagMapper articleTagMapper;
    private final UserService userService;

    // 根据标签名称查询
    @Override
    public Tag findByName(String tagName) {
        QueryWrapper<Tag> wrapper = new QueryWrapper<Tag>().eq("tag_name", tagName);
        return baseMapper.selectOne(wrapper);
    }

    // 根据标签id查询
    @Override
    public Tag findById(String id) {
        return baseMapper.selectById(id);
    }

    // 根据标签id数组查询
    @Override
    public Result<List<Tag>> findByIds(List<String> ids) {
        QueryWrapper<Tag> tagIds = new QueryWrapper<Tag>().in("id", ids);
        return Result.ok(baseMapper.selectList(tagIds));
    }

    @Override
    public Result<ResultEnum> addTag(TagVo tagVo) {
        // 1.根据token获取用户信息
        String userId = getUserIdFromToken();
        // 2.封装标签信息
        Tag tag = new Tag();
        String tagId = tagVo.getId();
        if (CharSequenceUtil.isBlank(tagId)) {
            tagId = String.valueOf(new IdWorker().nextId());
        }
        tag.setId(tagId);
        tag.setTagName(tagVo.getTagName());
        tag.setColor(tagVo.getColor());
        tag.setCreateUser(userId);
        tag.setCreateTime(LocalDateTime.now());
        // 3.新增标签
        if (baseMapper.insert(tag) > 0) {
            return Result.ok(ResultEnum.SUCCESS);
        }
        return Result.error(ResultEnum.FAIL);
    }

    // 获取标签列表
    @Override
    public Result<Object> getTagList(QueryVo queryVo) {
        // 1.获取用户信息
        String userId = getUserIdFromToken();
        // 2.获取查询条件
        String tagName = queryVo.getKeyword();
        // 3.封装查询条件
        QueryWrapper<Tag> wrapper = new QueryWrapper<>();
        if (tagName != null && !tagName.isEmpty()) {
            wrapper.eq(CREATE_USER, userId);
            wrapper.like("tag_name", tagName);
        }
        wrapper.eq(CREATE_USER, userId);
        wrapper.orderByDesc("create_time");
        // 4.分页条件，当前页、每页条数
        Page<Tag> page = new Page<>(queryVo.getCurrent(), queryVo.getLimit());
        Page<Tag> tagPage = page(page, wrapper);
        // 5.获取标签列表
        List<Tag> tags = tagPage.getRecords();
        // 6.获取所有标签的创建用户ID
        List<String> tagUserIds = tags.stream().map(Tag::getCreateUser).toList();
        // 7.获取所有标签的用户信息
        Map<String, User> userMap = userService.getUserMapByIds(tagUserIds);
        // 8.遍历标签列表，设置创建用户名称
        tags.forEach(tag -> {
            User user = userMap.get(tag.getCreateUser());
            if (user != null) {
                tag.setCreateUser(user.getUsername());
            }
        });
        // 8.封装返回结果
        Result<Object> result = new Result<>();
        result.setData(tagPage);
        return result;
    }

    // 发布文章获取标签列表
    @Override
    public Result<List<Tag>> getTagList() {
        return Result.ok(baseMapper.selectList(null));
    }

    // 更新标签
    @Override
    public Result<ResultEnum> updateTag(TagVo tagVo) {
        // 1.根据token获取用户信息
        String userIdFromToken = getUserIdFromToken();
        // 2.封装查询条件
        QueryWrapper<Tag> wrapper = new QueryWrapper<>();
        wrapper.eq(CREATE_USER, userIdFromToken);
        wrapper.eq("id", tagVo.getId());
        // 3.更新标签
        Tag tag = new Tag();
        tag.setTagName(tagVo.getTagName());
        tag.setColor(tagVo.getColor());
        tag.setUpdateTime(LocalDateTime.now());
        if (baseMapper.update(tag, wrapper) > 0) {
            return Result.ok(ResultEnum.SUCCESS);
        }
        return Result.error(ResultEnum.DATA_UPDATE_FAILED);
    }

    // 删除标签
    @Override
    public Result<ResultEnum> deleteTag(String id) {
        // 1.获取用户信息
        String userIdFromToken = getUserIdFromToken();

        // 2.封装查询条件，检查标签是否存在并属于当前用户
        QueryWrapper<Tag> tagWrapper = new QueryWrapper<>();
        tagWrapper.eq("create_user", userIdFromToken);
        tagWrapper.eq("id", id);
        // 3.检查标签是否存在
        Tag tag = baseMapper.selectOne(tagWrapper);
        if (tag == null) {
            return Result.error(ResultEnum.DATA_NOT_EXIST);
        }
        // 4.删除标签
        int deletedRows = baseMapper.delete(tagWrapper);
        if (deletedRows <= 0) {
            return Result.error(ResultEnum.DATA_DELETE_FAILED);
        }
        // 5.删除文章标签表中对应的标签
        QueryWrapper<ArticleTag> articleTagWrapper = new QueryWrapper<>();
        articleTagWrapper.eq("tag_id", id);
        articleTagMapper.delete(articleTagWrapper);

        return Result.ok(ResultEnum.SUCCESS);
    }

    // 批量删除标签
    @Override
    public Result<ResultEnum> deleteTagByIds(List<String> ids) {
        // 1.获取用户信息
        String userIdFromToken = getUserIdFromToken();
        // 2.封装查询条件，确保用户只能删除自己创建的标签
        QueryWrapper<Tag> tagWrapper = new QueryWrapper<>();
        tagWrapper.eq("create_user", userIdFromToken)
                .in("id", ids);
        // 3.查询要删除的标签
        List<Tag> tagsToDelete = baseMapper.selectList(tagWrapper);
        // 4.删除标签
        int deletedTagsCount = baseMapper.delete(tagWrapper);
        if (deletedTagsCount <= 0) {
            return Result.error(ResultEnum.DATA_DELETE_FAILED);
        }
        // 5.获取所有要删除的标签ID
        List<String> tagIdsToDelete = tagsToDelete.stream().map(Tag::getId).toList();
        // 6.删除文章标签表中对应的标签
        QueryWrapper<ArticleTag> articleTagWrapper = new QueryWrapper<>();
        articleTagWrapper.in("tag_id", tagIdsToDelete);
        articleTagMapper.delete(articleTagWrapper);
        return Result.ok(ResultEnum.SUCCESS);
    }

    @Override
    public Map<String, List<TagVo>> getTagNamesByArticleIds(List<String> articleIds) {
        // 1.如果传入空集合，返回空的Map
        if (articleIds == null || articleIds.isEmpty()) {
            return Collections.emptyMap();
        }
        // 2.创建查询条件
        QueryWrapper<ArticleTag> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("article_id", articleIds);
        // 3.执行查询
        List<ArticleTag> articleTags = articleTagMapper.selectList(queryWrapper);
        if (articleTags.isEmpty()) {
            return Collections.emptyMap();
        }
        // 4.按照文章ID分组，并将标签ID收集到列表中
        /*return articleTags.stream()
                .collect(Collectors.groupingBy(ArticleTag::getArticleId,
                        Collectors.mapping(ArticleTag::getTagId, Collectors.toList())));*/


        // 3.获取所有的 tagIds
        List<String> tagIds = articleTags.stream()
                .map(ArticleTag::getTagId)
                .distinct()
                .toList();
        // 4.查询 Tag 表
        QueryWrapper<Tag> tagQueryWrapper = new QueryWrapper<>();
        tagQueryWrapper.in("id", tagIds);
        List<Tag> tags = baseMapper.selectList(tagQueryWrapper);

        // 5.构建 TagId 到 TagVo 的映射
        Map<String, TagVo> tagIdToInfoMap = new HashMap<>();
        for (Tag tag : tags) {
            TagVo tagVo = new TagVo();
            tagVo.setId(tag.getId());
            tagVo.setTagName(tag.getTagName());
            tagVo.setColor(tag.getColor());
            tagVo.setCreateUser(tag.getCreateUser());
            tagVo.setCreateTime(tag.getCreateTime());
            tagVo.setUpdateTime(tag.getUpdateTime());
            tagIdToInfoMap.put(tag.getId(), tagVo);
        }

        // 6.构建 ArticleId 到 List<TagVo> 的映射
        Map<String, List<TagVo>> articleIdToTagInfosMap = new HashMap<>();
        for (ArticleTag articleTag : articleTags) {
            String articleId = articleTag.getArticleId();
            String tagId = articleTag.getTagId();
            TagVo tagVo = tagIdToInfoMap.get(tagId);
            if (tagVo != null) {
                articleIdToTagInfosMap
                        .computeIfAbsent(articleId, k -> new ArrayList<>())
                        .add(tagVo);
            }
        }
        return articleIdToTagInfosMap;
    }
}
